/*
 * This program sends periodically packets to a public id.
 * To be used in conjunction with recv_one_trigger or recv_two_triggers.
 * Usage:
 * > recv_public_trigger <cfg_file.xml>
 * > send_public_id <cfg_file.xml> <id>
 * (id is the ID of the receiver's public trigger, and is inserted 
 *  by the receiver program, recv_public_trigger)
 */ 

#include <stdio.h>
#include <errno.h>    

#include "i3.h"
#include "i3_client_api.h"
#include "utils.h"

#define TO_SEND_USEC 1000000
#define TO_SEND_SEC  0

void send_data(ID *id)
{
#define MY_PKT_SIZE 1000
  struct timeval tv;
  static long    seq = 0;
  long           temp; 
  int            k;
  static cl_buf *clb = NULL;

  if (clb == NULL) 
    clb = cl_alloc_buf(MY_PKT_SIZE);

  temp = htonl(++seq);
  memcpy(clb->data, &temp, sizeof(long));
  clb->data_len = MY_PKT_SIZE; 
    
  /* send packet */
  cl_send(id, clb, 0);
    
  printf("sent, seq. #: %ld\n", seq);

  /* set timer to send next packet */
  tv.tv_sec  = TO_SEND_SEC;
  tv.tv_usec = TO_SEND_USEC;
  cl_set_timer(&tv, send_data, id);
}  

void no_matching_trigger(void *ctx_data, void *data, void *fun_ctx)
{

    ID *id = (ID *) ctx_data;
    
  printf("Following ID not found, ");
  printf_i3_id(id, 0);
}

int i3_main_loop(char *cfg_file, char *str_id)
{
  struct timeval tv;
  ID             id;

  /* create and initialize the context */
  if (cl_init(cfg_file) != CL_RET_OK) {
    printf("Error creating context!\n");
    exit(-1);
  }

  /* read the ID of the receiver's trigger */
  read_id(&id, str_id);

  print_id(&id);

  /* set up the timer when the first packet is sent */
  tv.tv_sec  = TO_SEND_SEC;
  tv.tv_usec = TO_SEND_USEC;
  cl_set_timer(&tv, send_data, &id);

  /* exception when matching trigger not found */
  cl_register_callback(CL_CBK_TRIGGER_NOT_FOUND, no_matching_trigger, NULL);

  /* loop forever */
  cl_loop();

  /* destroy context */
  cl_exit();
}


int main(int argc, char **argv)
{
  if (argc != 3) {
    printf("%s <cfg_file.xml> <id>\n", argv[0], argv[1]);
    exit(-1);
  }
  
  i3_main_loop(argv[1], argv[2]);
  return -1;
}
